#
# Writes a matrix into dcsc format  header:JC:CP:IR:NUM

import random,sys
from numpy import linalg as LA
import numpy as np
import scipy.sparse as ss
import numpy.random as npr
import networkx as nx
import struct
import ctypes

n = 4000
p = 0.1
A = nx.fast_gnp_random_graph(n, p, directed=True)
print "generated gnp_random_graph"
A = nx.stochastic_graph(A)
print "generated stochastic"
B = ss.csc_matrix( nx.to_numpy_matrix(A))
print "generated csc"
del A
B = (B+B.T ) / 4
print "Made symmetric "
print "nnz: ", B.nnz
#print B.todense()

JC = sorted(list(set(B.tocsr().indices)))
CP = sorted(list(set(B.indptr)))
IR = B.indices
NUM = B.data
print "Made symmetric "

#print JC, "\n", CP, "\n", IR, "\n", NUM
size = 4*(4 + len(JC) + len(CP) + len(IR) + len(NUM))
bytes = ctypes.create_string_buffer(size)

offset = 0
for idx, val in enumerate([len(JC), len(CP) ,len(IR), len(NUM)]) :
	struct.pack_into('i', bytes, idx * 4, val)
	offset += 4;
print "packed header"

for idx, _list in enumerate(list([JC, CP, IR])) :
	for idx2, val in enumerate( _list ):
		struct.pack_into('i', bytes, offset, val )
		offset += 4
print "packed JC,CP,IR"
for val in NUM :
	struct.pack_into('f', bytes, offset, val )
	offset += 4
print "packed NUM"
filename =  "_".join(["dcsc_mat", "n"+str(n), "nnz" + str(B.nnz)])
print filename
filename = "../../data/" + filename

ss 	= "N\t" + str(n) + "\n"
ss +=  "nnz0\t" + str(B.nnz) + "\n"
B1 = B.todense()
ss += "L1\t" + str(LA.norm(B1, 1)) + "\n"
ss += "L2\t" + str(LA.norm(B1, 2)) + "\n"
B1 = B.dot(B)
ss += "nnz1\t" + str(B.nnz) + "\n"
B1 = B1.todense()
ss += "L1\t" + str(LA.norm(B1, 1)) + "\n"
ss += "L2\t" + str(LA.norm(B1, 2)) + "\n"
finfo = open(filename + ".info", "w")
finfo.write(ss)
finfo.close()
print "packed NUM"
filename += ".bin"
f = open(filename, 'wb')
f.write(bytes)
f.close()
